package com.example.interview.reflect01;

/**
 * @author ljsong
 * @date 2019/9/6  15:41
 */
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/** 原文： https://www.cnblogs.com/adamjwh/p/9683705.html
 *    转载文章：【动态页面】（三）之一：利用Java反射机制读取Jar包的类名和属性名  https://blog.csdn.net/gaoying_blogs/article/details/44263591
 *
 */
public class ReadJar {

    private static StringBuffer sBuffer;
//    private static String jar = "src/main/resources/lib/dt.jar";
    private static String jar = "D:\\000work\\project\\diy\\MiDengXing\\java-collection\\303-interview-project\\src\\main\\resources\\lib\\dt.jar";

    public static void main(String[] args) throws Exception {
        ReadJar.getJar(jar);
    }

    public static void getJar(String jar) throws Exception {
        try {
            File file = new File(jar);
            URL url = file.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[] { url },
                    Thread.currentThread().getContextClassLoader());

            JarFile jarFile = new JarFile(jar);
            Enumeration<JarEntry> enumeration = jarFile.entries();
            JarEntry jarEntry;

            sBuffer = new StringBuffer();    //存数据

            while (enumeration.hasMoreElements()) {
                jarEntry = enumeration.nextElement();

                if (jarEntry.getName().indexOf("META-INF") < 0) {
                    String classFullName = jarEntry.getName();
                    if (classFullName.indexOf(".class") < 0) {
                        classFullName = classFullName.substring(0, classFullName.length() - 1);
                    } else {
                        // 去除后缀.class，获得类名
                        String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");
                        Class<?> myClass = classLoader.loadClass(className);
                        sBuffer.append("类名\t：" + className);
                        System.out.println("类名\t：" + className);


                        // 获得属性名
//                        Class<?> clazz = Class.forName(className); // ClassNotFoundException
//                        Class<?> clazz = myClass;
                        Class<?> clazz = Class.forName(className, true, classLoader); // https://www.iteye.com/blog/chenzehe-1967070


                        Field[] fields = clazz.getDeclaredFields();
                        for (Field field : fields) {
                            sBuffer.append("属性名\t：" + field.getName() + "\n");
                            System.out.println("属性名\t：" + field.getName());
                            sBuffer.append("-属性类型\t：" + field.getType() + "\n");
                            System.out.println("-属性类型\t：" + field.getType());
                        }

                        // 获得方法名
                        Method[] methods = myClass.getMethods();
                        for (Method method : methods) {
                            if (method.toString().indexOf(className) > 0) {
                                sBuffer.append("方法名\t：" + method.toString().substring(method.toString().indexOf(className)) + "\n");
                                System.out.println("方法名\t：" + method.toString().substring(method.toString().indexOf(className)));
                            }
                        }
                        sBuffer.append("--------------------------------------------------------------------------------" + "\n");
                        System.out.println("--------------------------------------------------------------------------------");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sBuffer.append("End");
            System.out.println("End");

            write(sBuffer, pathname);    //写文件
        }
    }

    private static String pathname = "D:\\000work\\project\\diy\\MiDengXing\\java-collection\\303-interview-project\\src\\main\\java\\com\\example\\interview\\reflect01\\out.txt";

    public static void write(StringBuffer sBuffer, String pathname2) throws Exception {
        File file = new File(pathname2);
        BufferedWriter bw = new BufferedWriter(new FileWriter(file));

        bw.write(sBuffer.toString());
        bw.close();
    }

}
